﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;

namespace TestWPFEmguCV
{
    public class MatToBmp
    {
        public static Byte[] GetBMPFromYuv(byte[,,] matData, int width, int height)
        {
            DateTime startTime = DateTime.Now;

            // 写 BMP 图像文件。
            int yu = width * 3 % 4;
            int bytePerLine = 0;
            yu = yu != 0 ? 4 - yu : yu;
            bytePerLine = width * 3 + yu;
            List<byte> lisResult = new List<byte>();

            lisResult.AddRange(Encoding.ASCII.GetBytes("BM"));
            int length = bytePerLine * height + 54;

            lisResult.AddRange(GetBytes(length));
            lisResult.AddRange(GetBytes(0));
            lisResult.AddRange(GetBytes(54));
            lisResult.AddRange(GetBytes(40));
            lisResult.AddRange(GetBytes(width));
            lisResult.AddRange(GetBytes(height));
            lisResult.AddRange(GetBytes((ushort)1));
            lisResult.AddRange(GetBytes((ushort)24));
            lisResult.AddRange(GetBytes(0));
            lisResult.AddRange(GetBytes(bytePerLine * height));
            lisResult.AddRange(GetBytes(0));
            lisResult.AddRange(GetBytes(0));
            lisResult.AddRange(GetBytes(0));
            lisResult.AddRange(GetBytes(0));
            TimeSpan ts0 = DateTime.Now - startTime;
            byte[] data = new byte[bytePerLine * height];
            int gIndex = width * height;
            int bIndex = gIndex * 2;
            int uIndex = width * height;
            int vIndex = uIndex + ((width * height) >> 2);
            int halfWidth = width / 2;
            int temp = 0;
            int indexB = 0;
            int index = 0;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0, i = 0; x < width; x++)
                {
                    int yIndex = height - y - 1;
                    // R分量
                    //temp = matData[x, y, 0];

                    //index= data.Length- indexB
                    data[indexB] = matData[yIndex, x, 0];

                    // G分量
                    data[indexB + 1] = matData[yIndex, x, 1];

                    // B分量                 
                    data[indexB + 2] = matData[yIndex, x, 2];
                    indexB += 3;
                }
            }
           ;
            TimeSpan ts1 = DateTime.Now - startTime;

            lisResult.AddRange(data);
            Byte[] RE = lisResult.ToArray();
            TimeSpan ts2 = DateTime.Now - startTime;

            return RE;

        }

        private static byte[] GetBytes(int value)
        {
            byte[] lengBytes = new byte[4];
            lengBytes[0] = (byte)value;
            lengBytes[1] = (byte)(value >> 8);
            lengBytes[2] = (byte)(value >> 16);
            lengBytes[3] = (byte)(value >> 24);
            return lengBytes;
        }

        public static byte[] GetBytes(ushort value)
        {
            byte[] _buffer = new byte[2];
            _buffer[0] = (byte)value;
            _buffer[1] = (byte)(value >> 8);
            return _buffer;


        }

        public static Byte[] GetJpjByBmp(byte[] bmp)
        {
            //Byte[] bmp = File.ReadAllBytes(@"F:\海康摄像头\新建文件夹\2.bmp");
            DateTime startTime = DateTime.Now;
            Stream stream = new MemoryStream(bmp);
            Bitmap bitmap = new Bitmap(stream);

            Emgu.CV.Image<Bgr, UInt16> ImageEmgu = new Image<Bgr, UInt16>(bitmap.Width, bitmap.Height);
            ImageEmgu = BitmapExtension.ToImage<Bgr, UInt16>(bitmap);
            Mat image = ImageEmgu.Mat;

            using (VectorOfByte buf = new VectorOfByte())
            {
                string ext = ".jpg";
                //ext = ".png";

                CvInvoke.Imencode(ext, image, buf, null);
                byte[] array = buf.ToArray();
                return array;
            }


        }

        public static Byte[] GetJpjByBmpUseSixLab(byte[] bmp)
        {
            var image = SixLabors.ImageSharp.Image.Load(bmp);
            MemoryStream stream = new MemoryStream();

            image.SaveAsJpeg(stream);
            return stream.GetBuffer();

            //image.Save(stream, new JpegEncoder());
            //var reader = new BinaryReader(stream);
            //var result= reader.ReadBytes();
            ////stream.Write();
            //return stream.
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="image"></param>
        /// <param name="ext">.jpg  .png .bmp</param>
        /// <returns></returns>
        public static Byte[] GetBytesByMat(Mat image, string ext)
        {
            using (VectorOfByte buf = new VectorOfByte())
            {
                CvInvoke.Imencode(ext, image, buf, null);
                byte[] array = buf.ToArray();
                return array;
            }
        }
    }
}
